package com.stores.v1.security;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.stores.v1.entity.Person;
import com.stores.v1.entity.SiteAdmin;
import com.stores.v1.model.DatabaseCommandException;
import com.stores.v1.toolset.DatabaseInitializationException;
import com.stores.v1.toolset.IDatabase;

public class AccessControl implements IAccessControl {
	private IDatabase database;
	private Person userContext;
	private int privilegeId;

	@Override
	public Person getUserContext() {
		return this.userContext;
	}

	@Override
	public void setUserContext(Person person) {
		this.userContext = person;
	}

	@Override
	public IDatabase getDatabase() {
		return database;
	}

	@Override
	public void setDatabase(IDatabase database) {
		this.database = database;
	}

	@Override
	public boolean isAllowed() throws DatabaseInitializationException,
			DatabaseCommandException {
		if (this.getUserContext().getClass().equals(SiteAdmin.class))
			return true;// full access to site admins

		StringBuilder sql = new StringBuilder();
		Connection connection = this.getDatabase().getOpenConnection();
		boolean isAllowed = false;
		sql.append("select count(p.privilegeId) as isAllowed ");
		sql.append("from privilege p ");
		sql.append("inner join groupprivileges gp ");
		sql.append("on gp.privilegeId = p.privilegeId ");
		sql.append("inner join usergroups ug ");
		sql.append("on ug.groupId = gp.groupId ");
		sql.append("where ug.personId = ? and p.privilegeId = ?");
		try {
			PreparedStatement command = connection.prepareStatement(sql
					.toString());
			command.setInt(1, this.getUserContext().getId());
			command.setInt(2, privilegeId);
			ResultSet result = command.executeQuery();
			if (result.next()) {
				isAllowed = result.getInt("isAllowed") > 0;
			}
		} catch (SQLException e) {
			throw new DatabaseCommandException(String.format(
					"Failed to get privileges for user [%d] due to [%s]", this
							.getUserContext().getId(), e.getMessage()));
		}
		return isAllowed;
	}

	@Override
	public int getPrivilegeId() {
		return this.privilegeId;
	}

	@Override
	public void setPrivilegeId(int privilegeId) {
		this.privilegeId = privilegeId;
	}
}
